package Fuzzy;

import Parser.*;
import java.util.Vector;
import java.lang.*;
import java.math.*;

public class Fuzzyfication
{
        //attributen
        private KBParser kbpParser;
        private Variables vrbVariable;
        private double result;
        private Vector vctResults;
        private boolean blnPrintProgress;
        private String strUniverse;


        //constructor
		public Fuzzyfication(KBParser parse)
        {
            kbpParser = parse;
            vctResults = new Vector();
            blnPrintProgress = false;
        }

        //methods
        public Variables MakeVariableFuzzy()
        {
            return vrbVariable;
        }
		
		//Vector vullen met string result
        public Vector calcUniverseValues( double value, String strName)
        {

            for(int x=0; x<kbpParser.GetVariables().size();x++)
            {
                if(getWord(kbpParser.GetVariables().elementAt(x).toString(),0).equals(strName))
                {
                    strUniverse = getWord(kbpParser.GetVariables().elementAt(x).toString(),1);
                    if(blnPrintProgress)
                    {
                        System.out.println("variableName: " + strName);
                        System.out.println("universeName: " + strUniverse);
                    }
                }
            }

			vctResults.add(strName);

            for(int i=0; i<kbpParser.getUniverse(strUniverse).getSetCount(); i++)
            {

                String strSetname = kbpParser.getUniverse(strUniverse).getSet(i).GetName();
                vctResults.add(strSetname);

                double result = calcSetValues(value,strUniverse,Setname);
                String strResult = "" + result;
                result = 0;
                vctResults.add(strResult);
            }

            return vctResults;
        }

		
        public double calcSetValues(double value, String strName, String strSetName)
        {
            double tempvalue = value;
            double x1;
            double x2;
            double x3;
            double x4;
			if (value < 0 && kbpParser.getUniverse(strName).getSet(strSetName).GetX4() < 0)
            {
				x1 = Math.sqrt(Math.pow(kbpParser.getUniverse(strName).getSet(strSetName).GetX1(), 2));
				x2 = Math.sqrt(Math.pow(kbpParser.getUniverse(strName).getSet(strSetName).GetX2(), 2));
				x3 = Math.sqrt(Math.pow(kbpParser.getUniverse(strName).getSet(strSetName).GetX3(), 2));
				x4 = Math.sqrt(Math.pow(kbpParser.getUniverse(strName).getSet(strSetName).GetX4(), 2));
                value = Math.sqrt(Math.pow(value, 2));
            }
            else
            {
				x1 = kbpParser.getUniverse(strName).getSet(strSetName).GetX1();
				x2 = kbpParser.getUniverse(strName).getSet(strSetName).GetX2();
				x3 = kbpParser.getUniverse(strName).getSet(strSetName).GetX3();
				x4 = kbpParser.getUniverse(strName).getSet(strSetName).GetX4();
                value = tempvalue;

            }
            if(x4<x1)
            {
				x1 = Math.sqrt(Math.pow(kbpParser.getUniverse(strName).getSet(strSetName).GetX4(), 2));
				x2 = Math.sqrt(Math.pow(kbpParser.getUniverse(strName).getSet(strSetName).GetX3(), 2));
				x3 = Math.sqrt(Math.pow(kbpParser.getUniverse(strName).getSet(strSetName).GetX2(), 2));
				x4 = Math.sqrt(Math.pow(kbpParser.getUniverse(strName).getSet(strSetName).GetX1(), 2));
            }

            if((value>=x1) && (value<=x4))
            {
                    if(x1==x2 && x1==x3)
                    {
                        // low
                        result = 1-(1/(x4-x1))*(value-x1);
                    }
                    else
                    {
                            if(x2==x3 && x3==x4)
                            {
                                // high
                                result = ((1/(x4-x1))*(value-x1));
                            }
                            else
                            {
                                    if(x1!=x2 && x3!=x4 && x2==x3)
                                    {
                                        // medium
                                        if(value<x2)
                                            {
                                                    result = (1/(x2-x1))*(value-x1);
                                            }
                                            if(value>x3)
                                            {
                                                    result = 1-((1/(x4-x3))*(value-x3));
                                            }
                                            if(value>=x2 && value<=x3)
                                            {
                                                    result = 1;
                                            }
                                    }
                            }
                    }
            }
            else
            {
                result =0;
            }
			//Als messaging aan staat, bericht tonen
            if(blnPrintProgress)
            {
                System.out.println("** FUZZIFICATIE UniverseName: " + strName + " **");
				System.out.println("** FUZZIFICATIE Used value  : " + value + " **");
				System.out.println("** FUZZIFICATIE SetName     : " + strSetName + " **");
				System.out.println("** FUZZIFICATIE X1          : " + x1 + " **");
				System.out.println("** FUZZIFICATIE X2          : " + x2 + " **");
				System.out.println("** FUZZIFICATIE X3          : " + x3 + " **");
				System.out.println("** FUZZIFICATIE X4          : " + x4 + " **");
				System.out.println("** FUZZIFICATIE Result      : " + result + " **");
            }
            return result;
        }

		private String getWord(String strSet, int nr)
		{
			int currentWord = 0;
			int i = 0;

			////Eerste en laatste spatie vervangen voor een [ of een ]
			strSet = strSet.replace('[',' ');
			strSet = strSet.replace(']',' ');
			strSet = strSet.trim();

			while(strSet.length() > 0) {
			  if(i == strSet.length() || strSet.charAt(i) == '\n' || strSet.charAt(i) == ' ' || strSet.charAt(i) == '\t') {
				//einde van huidige woord gevonden
				if(nr == currentWord) {  //huidige woord moet worden teruggegeven
				  return (strSet.substring(0, i)).trim();
				}
				//nog niet het goede woord, doorgaan met volgende woord zoeken
				strSet = (strSet.substring(i, strSet.length())).trim();
				i=0;
				currentWord++;
			  }
			  i++;
			}
			return null;
		}
}
